﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace colas
{
    class EventoFinCompraTicket: IEvento
    {
        private double tCompraTicket;
        private double tMedioEntregaPedido;
        private gridline linea_actual;

        public EventoFinCompraTicket(double tCompraTicket, double tEntregaPedido)
        {
            this.tCompraTicket = tCompraTicket;
            this.tMedioEntregaPedido = tEntregaPedido;
        }

        public gridline llenarLinea(gridline linea_anterior)
        {            
            if (linea_anterior.estado_cajero== (int)Utils.cajero.LIBRE)            
                System.Windows.Forms.MessageBox.Show("El cajero debería haber estado Ocupado en el evento"); 
           
            linea_actual = new gridline(linea_anterior); 
            linea_actual.Reloj = linea_anterior.fin_ticket;
            linea_actual.fin_ticket = -1;
            linea_actual.evento = (int)Utils.eventos.FIN_COMPRA_TICKET;
            
            if (linea_anterior.cola_cajero > 0)
            {
                //HAY COLA                
                linea_actual.estado_cajero = (int)Utils.cajero.OCUPADO;
                linea_actual.cola_cajero = linea_anterior.cola_cajero -1;
                //busco el cliente que está en cola
                bool encontrado = false;
                foreach (Cliente c in gridline.clientes)
                {
                    if (c.estado == (int)Utils.cliente.EN_COLA_TICKET)
                    {
                        c.estado = (int)Utils.cliente.ESPERANDO_TICKET;
                        linea_actual.fin_ticket = linea_actual.Reloj + 20;
                        encontrado = true;
                        break;
                    }                                        
                }
                if (encontrado == false)
                    System.Windows.Forms.MessageBox.Show("Error, no se encontró ningún cliente con estado en cloa ticket y teóricamente si hay cola. CHAN!");
            }
            else
            {
                //NO HAY NADIE EN COLA                
                linea_actual.estado_cajero = (int) Utils.cajero.LIBRE;
                linea_actual.fin_ticket = -1;                    
            }

            //Defino que pasa con el cliente que acaba de recibir el ticket

             Cliente cliente_que_recibio_ticket = obtener_cliente_esperando_ticket();
            

            if (linea_anterior.estado_empleado1 == (int)Utils.empleado.LIBRE || linea_anterior.estado_empleado2 == (int)Utils.empleado.LIBRE)
            {               
                if (linea_anterior.estado_empleado1 == (int)Utils.empleado.LIBRE)
                {
                    //Por defecto va al Empleado1 
                    linea_actual.estado_empleado1 = (int)Utils.empleado.OCUPADO;
                    linea_actual.estado_empleado2 = linea_anterior.estado_empleado2;
                    linea_actual.fin_entrega1 = linea_actual.Reloj+calcular_proxima_fin_entrega(1);
                    linea_actual.fin_entrega2 = linea_anterior.fin_entrega2;
                }
                else
                {
                    //EL cliente va al Empleado 2 
                    linea_actual.estado_empleado2 = (int)Utils.empleado.OCUPADO;
                    linea_actual.estado_empleado1 = (int)Utils.empleado.OCUPADO;
                    linea_actual.fin_entrega2 = linea_actual.Reloj+calcular_proxima_fin_entrega(2);
                    linea_actual.fin_entrega1 = linea_anterior.fin_entrega1;
                }
                cliente_que_recibio_ticket.estado = (int)Utils.cliente.ESPERANDO_ENTREGA;

            }
            else
            {
                //No hay empleado libre, a la cola pa!
                linea_actual.cola_entrega = linea_anterior.cola_entrega + 1;
                cliente_que_recibio_ticket.estado = (int)Utils.cliente.EN_COLA_ENTREGA;
            }
            
                                    
            return linea_actual;                        
            
        }
        private double calcular_proxima_fin_entrega(int i)
        {
            double rand = NumeroRandom.getInstance().NextDouble();
            double tiempo_fin = -1 * tMedioEntregaPedido * (Math.Log(1 - rand));
            if (i == 1)
            {
                linea_actual.rnd_entrega1 = rand;
                linea_actual.rnde_entrega1 = tiempo_fin;
            }
            else
            {
                linea_actual.rnd_entrega2 = rand;
                linea_actual.rnde_entrega2 = tiempo_fin;
            }
            
            return tiempo_fin;            
        }

        private Cliente obtener_cliente_esperando_ticket()
        {
            bool encontrado = false;
            foreach (Cliente c in gridline.clientes)
            {                
                if (c.estado == (int)Utils.cliente.ESPERANDO_TICKET)
                {                    
                    encontrado = true;
                    return c;
                }             
            }
            if (!encontrado)
                System.Windows.Forms.MessageBox.Show("Error. No se encontró un Cliente en estado esperando ticket. Quizás tuvo alguna emergencia");
            return null;
        }


    }

    
}
